package easamples;

import java.io.File;

import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;

import org.sparx.Collection;
import org.sparx.Connector;
import org.sparx.ConnectorConstraint;
import org.sparx.ConnectorEnd;
import org.sparx.ConnectorTag;
import org.sparx.Element;
import org.sparx.Repository;

public class ConnectorExample implements IExample
{
	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		return "Connector Test";
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.sparx.javaexample.test.IExample#getDescription()
	 */
	public String getDescription()
	{
		return "Links two diagram objects with a connector.<br/><br/><b>NOTE:</b> Requires element ids for the Source and Target elements, so try running <code>Dump Model Diagrams</code> or <code>Dump Model</code> first and note some suitable element IDs down.<br/><br/><b>Related APIs</b><br/><ul><li><a href='http://www.sparxsystems.com.au/EAUserGuide/index.html?connector2_2.htm'>Connector API</a></li></ul>";
	}

	/*
	 * (non-Javadoc)
	 * @see org.sparx.javaexample.test.IExample#runExample(java.io.File, javax.swing.DefaultListModel)
	 */
	public void runExample( File projectFile, ExampleUI uiFrame )
	{
		DefaultListModel outputList = uiFrame.getOutputListModel();
		
		// Prompt the user for some Element IDs to connect
		// Source element
		short sourceElementID = ExampleHelpers.promptForShortID( 
				"Enter an Element ID to use as the source element", uiFrame);
		
		if ( sourceElementID < 0 )
		{
			outputList.addElement( "Connector Example cancelled by user" );
			return;
		}
		
		// Target element
		short targetElementID = ExampleHelpers.promptForShortID( 
				"Enter an Element ID to use as the target element", uiFrame);
		
		if ( targetElementID < 0 )
		{
			outputList.addElement( "Connector Example cancelled by user" );
			return;
		}
		
		Repository rep = null;
		
		try
		{
			// Create a repository object - This will create a new instance of EA
			rep = new Repository();
			
			// Attempt to open the provided file
			if ( rep.OpenFile(projectFile.getAbsolutePath()) )
			{
				// Get the elements to connect
				Element sourceElement = rep.GetElementByID( sourceElementID );
				Element targetElement = rep.GetElementByID( targetElementID );
				
				// ==================================================
				// CREATE CONNECTOR
				// ==================================================
				// Create the connector, set its endpoint and save it
				Connector theConnector = sourceElement.GetConnectors().AddNew( 
						"Test Association", "Association" );
				theConnector.SetSupplierID( targetElement.GetElementID() );
				theConnector.Update();
				
				// Refresh the connectors collection to include the newly created connector
				sourceElement.GetConnectors().Refresh();
				
				outputList.addElement( "Connector created between " + sourceElement.GetName() 
						+ " and " + targetElement.GetName() );
				
				// ==================================================
				// ADD CONSTRAINTS
				// ==================================================
				Collection<ConnectorConstraint> constraints = theConnector.GetConstraints();
				ConnectorConstraint theConstraint = constraints.AddNew( "Test Constraint", "Invariant" );
				outputList.addElement( "Constraint added to connector between " + sourceElement.GetName() 
						+ " and " + targetElement.GetName() );
				theConstraint.Update();
				
				// ==================================================
				// ADD TAGGED VALUES
				// ==================================================
				Collection<ConnectorTag> taggedValues = theConnector.GetTaggedValues();
				ConnectorTag theTaggedValue = taggedValues.AddNew( "Test TV", "TestValue" );
				theTaggedValue.Update();
				outputList.addElement( "Tagged Value added to connector between " + sourceElement.GetName() 
						+ " and " + targetElement.GetName() );
				
				// ==================================================
				// SET CLIENT AND SUPPLIER ROLES
				// ==================================================
				ConnectorEnd clientEnd = theConnector.GetClientEnd();
				clientEnd.SetVisibility( "Private" );
				clientEnd.SetRole( "m_client" );
				clientEnd.Update();
				
				ConnectorEnd supplierEnd = theConnector.GetSupplierEnd();
				supplierEnd.SetVisibility( "Protected" );
				supplierEnd.SetRole( "m_supplier" );
				supplierEnd.Update();
				
				outputList.addElement( "Client and Supplier roles set on connector between " 
						+ sourceElement.GetName() + " and " + targetElement.GetName() );
				
				outputList.addElement( "    Client: " + clientEnd.GetRole() );
				outputList.addElement( "    Supplier: " + supplierEnd.GetRole() );
				
				outputList.addElement( "Done!" );
			}
			else
			{
				// If the file couldn't be opened then notify the user
				String message = "EA was unable to open the file '";
				message += projectFile.getAbsolutePath();
				message += "'.";
				JOptionPane.showMessageDialog( uiFrame, message, "Invalid File", JOptionPane.ERROR_MESSAGE );
				outputList.addElement( message );
			}
		}
		catch ( UnsatisfiedLinkError ule )
		{
			String message = "Unable to communicate with EA.\nPlease ensure that the path to SSJavaCOM.dll included in java.library.path";
			JOptionPane.showMessageDialog( uiFrame, message, "Unable to link to SSJavaCOM.dll", JOptionPane.ERROR_MESSAGE );
			outputList.addElement( message );
		}
		catch ( Exception e )
		{
			String message = "An unhandled exception was thrown: " + e.getMessage();
			JOptionPane.showMessageDialog( uiFrame, message, "Unhandled Exception", JOptionPane.ERROR_MESSAGE );
			outputList.addElement( message );
		}
		finally
		{
			if ( rep != null )
			{
				// Clean up
				rep.CloseFile();
				rep.Exit();
				rep.destroy();
			}
		}
		
	}
}
